import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'el-input-number',
  templateUrl: './input-number.component.html',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: InputNumberComponent,
    multi: true
  }],
})
export class InputNumberComponent implements OnInit, ControlValueAccessor {
  private controlChange: any = function () { };
  private controlTouch: any = function () { };
  @Input() disabled: boolean = false;
  @Input() min: number = 0;
  @Input() max: number = Number.MAX_SAFE_INTEGER;
  @Input() step: number = 1;
  @Input('step-strictly') stepStrictly: boolean = true;
  @Input() size: string = '';
  @Input() controls: boolean = true;
  @Input('controls-position') controlsPosition: string = '';
  @Input() debounce: number = 300;
  @Input() precision: number = 0;
  @Input() placeholder: string = '';
  @Input() model: number = 0;
  @Output('change') modelChange: EventEmitter<number> = new EventEmitter();
  minDisabled: boolean = false;
  maxDisabled: boolean = false;

  constructor() { }

  writeValue(value: any): void {
    this.model = value;
  }
  registerOnChange(fn: any): void {
    this.controlChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.controlTouch = fn;
  }

  changeHandle(value: any) {
    var /** @type {?} */ oldValue = this.model;
    this.model = value;
    if (Number.isNaN(+this.model)) {
      this.model = oldValue;
      return;
    }

    this.maxDisabled = value > this.max;
    this.minDisabled = value < this.min;
    if (this.maxDisabled)
      return this.dispatchModel(this.max);
    if (this.minDisabled)
      return this.dispatchModel(this.min);
    
    this.modelChange.emit(value);
  }

  burlHandle(value:number){

    if (this.stepStrictly) {
      var len = 0;
      var str = String(this.step).indexOf('.');
      if (str !== -1) {
        len = (String(this.step).length - str - 1);
      } else {
        len = String(this.step).length;
      }

      const precisionFactor = Math.pow(10, len);
     
      value = value - (value%(this.step * precisionFactor));
      
    }
    if (this.precision > 0 && (String(value).indexOf('.') !== -1)) {
      value = Number(value.toFixed(this.precision));
    }

    this.model = value;
    this.modelChange.emit(value);
  }

  dispatchModel(limit: any) {
    var _this = this;
    var /** @type {?} */ timer = setTimeout(function () {
      _this.model = limit;
      _this.modelChange.emit(limit);
      clearTimeout(timer);
    }, this.debounce);
  }

  decreaseHandle(calcType: any) {
    if (calcType === void 0) { calcType = true; }
    if (this.disabled)
      return;
    var /** @type {?} */ step = calcType ? this.step : 0 - this.step;
    var /** @type {?} */ val: any = Number(this.model) + step;
    if (Number.isNaN(val))
      return;
    
    this.maxDisabled = val > this.max;
    this.minDisabled = val < this.min;
    if (!this.maxDisabled && !this.minDisabled) {
      this.model = val;
      this.modelChange.emit(this.model);
      this.controlChange(this.model);
    }
  }


  ngOnInit(): void {
  }

}
